import requests
import json
import io
import random
import time
import re
import pyDes
import base64
import uuid
import sys
import os
import hashlib
from Crypto.Cipher import AES


class DailyCP:
    def __init__(self, schoolName):
        self.key = "b3L26XNL"  # "ST83=@XV"#dynamic when app update版本低了请改这个
        self.session = requests.session()
        self.host = ""
        self.loginUrl = ""
        self.isIAPLogin = True
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37",
            # "X-Requested-With": "XMLHttpRequest",
            "Pragma": "no-cache",
            "Accept": "application/json, text/plain, */*",
            # "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            # "User-Agent": "okhttp/3.12.4"
        })
        extension = {"deviceId": str(uuid.uuid4()), "systemName": "未来操作系统", "userId": "5201314", "appVersion": "8.1.13",
                     "model": "红星一号量子计算机", "lon": 0.0, "systemVersion": "初号机", "lat": 0.0}
        self.session.headers.update({"Cpdaily-Extension": self.encrypt(json.dumps(extension))})
        self.setHostBySchoolName(schoolName)

    def setHostBySchoolName(self, schoolName):
        ret = self.request("https://static.campushoy.com/apicache/tenantListSort")
        school = [j for i in ret["data"] for j in i["datas"] if j["name"] == schoolName]
        if len(school) == 0:
            print("不支持的学校或者学校名称错误,以下是支持的学校列表")
            print(ret)
            exit()
        ret = self.request(
            "https://mobile.campushoy.com/v6/config/guest/tenant/info?ids={ids}".format(ids=school[0]["id"]))
        self.loginUrl = ret["data"][0]["ampUrl"]
        if ret == "":
            print("学校并没有申请入驻今日校园平台")
            exit()
        print("{name}的登录地址{url}".format(name=schoolName, url=self.loginUrl))
        self.host = re.findall(r"//(.*?)/", self.loginUrl)[0]

    def encrypt(self, text):
        k = pyDes.des(self.key, pyDes.CBC, b"\x01\x02\x03\x04\x05\x06\x07\x08", pad=None, padmode=pyDes.PAD_PKCS5)
        ret = k.encrypt(text)
        return base64.b64encode(ret).decode()

    def passwordEncrypt(self, text: str, key: str):
        pad = lambda s: s + (len(key) - len(s) % len(key)) * chr(len(key) - len(s) % len(key))
        # unpad = lambda s: s[:-ord(s[len(s) - 1:])]
        text = pad("TdEEGazAXQMBzEAisrYaxRRax5kmnMJnpbKxcE6jxQfWRwP2J78adKYm8WzSkfXJ" + text).encode("utf-8")
        aes = AES.new(str.encode(key), AES.MODE_CBC, str.encode("ya8C45aRrBEn8sZH"))
        return base64.b64encode(aes.encrypt(text))

    def request(self, url: str, body=None, parseJson=True, JsonBody=True, Referer=None):
        url = url.format(host=self.host)
        if Referer != None: self.session.headers.update({"Referer": Referer})
        if body == None:
            ret = self.session.get(url)
        else:
            self.session.headers.update(
                {"Content-Type": ("application/json" if JsonBody else "application/x-www-form-urlencoded")})
            ret = self.session.post(url, data=(json.dumps(body) if JsonBody else body))
        # print(json.loads(ret.text))
        if parseJson:
            return json.loads(ret.text)
        else:
            return ret

    def decrypt(self, text):
        k = pyDes.des(self.key, pyDes.CBC, b"\x01\x02\x03\x04\x05\x06\x07\x08", pad=None, padmode=pyDes.PAD_PKCS5)
        ret = k.decrypt(base64.b64decode(text))
        return ret.decode()

    def checkNeedCaptcha(self, username):
        url = "https://{host}/iap/checkNeedCaptcha?username={username}".format(host=self.host, username=username)
        ret = self.session.get(url)
        ret = json.loads(ret.text)
        return ret["needCaptcha"]

    def generateCaptcha(self):
        # url = "https://{host}/iap/generateCaptcha?ltId={client}&codeType=2".format(host=self.host,client=self.client)
        # ret = self.session.get(url)
        # return ret.content
        pass

    def getBasicInfo(self):
        return self.request("https://{host}/iap/tenant/basicInfo", "{}")

    def login(self, username, password, captcha=""):
        print('登陆状态' + self.loginUrl)
        return self.loginIAP(username, password, captcha)

    def loginIAP(self, username, password, captcha=""):
        self.session.headers.update({"X-Requested-With": "XMLHttpRequest"})
        ret = self.session.get(
            "https://{host}/iap/login?service=https://{host}/portal/login".format(host=self.host)).url
        client = ret[ret.find("=") + 1:]
        ret = self.request("https://{host}/iap/security/lt", "lt={client}".format(client=client), True, False)
        client = ret["result"]["_lt"]
        # self.encryptSalt = ret["result"]["_encryptSalt"]
        body = {
            "username": username,
            "password": password,
            "lt": client,
            "captcha": captcha,
            "rememberMe": "true",
            "dllt": "",
            "mobile": ""
        }
        ret = self.request("https://{host}/iap/doLogin", body, True, False)
        if ret["resultCode"] == "REDIRECT":
            self.session.get(ret["url"])
            return True
        else:
            return False

    def checkNeedCaptchaAuthServer(self, username):
        ret = self.request(
            "http://{host}/authserver/needCaptcha.html?username={username}&pwdEncrypt2=pwdEncryptSalt".format(
                username=username), parseJson=False).text
        return ret == "true"

    def getCollectorList(self):
        body = {
            "pageSize": 10,
            "pageNumber": 1
        }
        ret = self.request("https://{host}/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList",
                           body)
        ##返回最新的收集表
        print(ret)
        return ret["datas"]["rows"]

    def getNoticeList(self):
        body = {
            "pageSize": 10,
            "pageNumber": 1
        }
        ret = self.request("https://{host}/wec-counselor-stu-apps/stu/notice/queryProcessingNoticeList", body)
        print(ret)
        return ret["datas"]["rows"]

    def confirmNotice(self, wid):
        body = {
            "wid": wid
        }
        ret = self.request("https://{host}/wec-counselor-stu-apps/stu/notice/confirmNotice", body)
        print(ret["message"])
        return ret["message"] == "SUCCESS"

    def getCollectorDetail(self, collectorWid):
        body = {
            "collectorWid": collectorWid
        }
        return self.request("https://{host}/wec-counselor-collector-apps/stu/collector/detailCollector", body)["datas"]

    def getCollectorFormFiled(self, formWid, collectorWid):
        body = {
            "pageSize": 50,
            "pageNumber": 1,
            "formWid": formWid,
            "collectorWid": collectorWid
        }
        print(formWid, collectorWid)
        return self.request("https://{host}/wec-counselor-collector-apps/stu/collector/getFormFields", body)["datas"][
            "rows"]

    def submitCollectorForm(self, formWid, collectWid, schoolTaskWid, rows, address):
        body = {
            "formWid": formWid,
            "collectWid": collectWid,
            "schoolTaskWid": schoolTaskWid,
            "form": rows,
            "address": address,
            "uaIsCpadaily": True
        }
        ret = self.request("https://{host}/wec-counselor-collector-apps/stu/collector/submitForm", body)
        print(ret)
        ##返回今日打卡结果
        Message = message()
        Message.sendMessage(ret["message"])
        print('打卡结果:' + ret["message"])
        return ret["message"] == "SUCCESS"

    def autoFill(self, rows):
        for item in rows:
            index = 0
            while index < len(item["fieldItems"]):
                if item["fieldItems"][index]["isSelected"] == 1:
                    index = index + 1
                else:
                    item["fieldItems"].pop(index)

    def getFormCharac(self, detail):
        ret = self.request(detail["content"], parseJson=False, JsonBody=False)
        return hashlib.md5(ret.content).digest().hex()

    def autoComplete(self, address):
        collectList = self.getCollectorList()
        for item in collectList:
            detail = self.getCollectorDetail(item["wid"])
            form = self.getCollectorFormFiled(detail["collector"]["formWid"], detail["collector"]["wid"])

            ##从这里开始填写表单数据：见最下方说明
            form[0]['fieldItems'][0]['isSelected'] = 1
            form[1]['fieldItems'][0]['isSelected'] = 1
            form[2]['fieldItems'][0]['isSelected'] = 1
            form[3]['fieldItems'][0]['isSelected'] = 1
            ##截至

            self.autoFill(form)
            self.submitCollectorForm(detail["collector"]["formWid"], detail["collector"]["wid"],
                                     detail["collector"]["schoolTaskWid"], form, address)
            exit()

        confirmList = self.getNoticeList()
        print(confirmList)
        for item in confirmList: self.confirmNotice(item["noticeWid"])


class message:
    def sendMessage(self, content):
        data ={'msg':str('[今日校园打卡]' +'\n'+ content+'\n'+self.datetime())}
        ret = requests.post("你自己的接收消息的接口",data=data)
        print(ret.content)

def main_handler(event, context):
    userinfo = ["学校名称", "学号", "密码", "签到地址"]
    app = DailyCP(userinfo[0])
    app.login(userinfo[1], userinfo[2])
    app.autoComplete(userinfo[3])

##测试 main_handler(1, 2)

'''
    需要填写的内容：
    1.填写main_handler中的 userinfo = ["学校名称", "学号", "密码", "签到地址"]
    
    2.填写表单函数：autoComplete
        类型1  选择题
        A:[题目号]填写数值：题目号-1   例如：第一题则为：1-1=0 填写0 依次类推
        B:[题目号]填写数值: 答案号-1   例如：第一题选择答案第一个则为：1-1=0 填写0
        form[A]['fieldItems'][B]['isSelected'] = 1
        
        类型2  填空题、或者下拉菜单题
        A:[题目号]填写数值：题目号-1   例如：第一题则为：1-1=0 填写0 依次类推
        form[A]['value']='湖北省/武汉市/武昌区'  ====>对应下拉菜单题，“/”不能掉了
        form[A]['value']='无'  ====>对应填空题
    
    3.消息推送函数：message中的消息接收地址
        自己写扩展函数：邮件，短信，微信，QQ都可以，自己找接口
'''


